package hibari.client.ui;

import hibari.client.Book;
import hibari.client.model.ClientServices;
import hibari.client.model.Week;

import java.util.HashMap;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.TableElement;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

public class WeekViewer extends Composite implements LoadHandler<MusicViewer> {

	interface WeekViewerUiBinder extends UiBinder<Widget, WeekViewer> {
	}

	private static WeekViewerUiBinder uiBinder = GWT.create(WeekViewerUiBinder.class);

	@UiField
	protected DonateButton donateButton;

	@UiField
	protected TableElement layoutTable;

	@UiField
	protected MusicViewer leftMusicViewer;

	@UiField
	protected MusicViewer rightMusicViewer;
	@UiField
	protected Label title;

	@UiField
	protected ImageElement icon;

	private Map<Integer, Week> cache = new HashMap<Integer, Week>();

	private Week week;

	public WeekViewer() {
		initWidget(uiBinder.createAndBindUi(this));
		this.leftMusicViewer.setLoadHandler(this);
		this.rightMusicViewer.setLoadHandler(this);
		this.leftMusicViewer.init();
		this.rightMusicViewer.init();
		showLoading();
	}

	private void finishLoading() {
		WeekViewer.this.layoutTable.removeClassName("hide");
		Book.getInstance().hideLoading();

		DateTimeFormat format = DateTimeFormat.getFormat("yyyy-MM-dd");
		this.title.setText(format.format(this.week.getDate()));
		this.donateButton.setWeekNumber(this.week.getWeekNumber());

		if (this.week.getBackgroundColor() != null) {
			getElement().getStyle().setBackgroundColor("#" + this.week.getBackgroundColor());
		}

		if (this.week.getImageId() != null) {
			getElement().getStyle().setBackgroundImage("url(\"/image?id=" + this.week.getImageId() + "\")");
		} else {
			getElement().getStyle().setBackgroundImage("");
		}

		if (this.week.getIconId() != null) {
			this.icon.setSrc("/image?id=" + this.week.getIconId());
			this.icon.getStyle().setDisplay(Display.INLINE);
		} else {
			this.icon.getStyle().setDisplay(Display.NONE);
		}
	}

	public void setWeek(int weekNumber) {
		if (this.week != null && this.week.getWeekNumber() == weekNumber) {
			return;
		}

		Week cachedWeek = this.cache.get(weekNumber);
		if (cachedWeek != null) {
			setWeek(cachedWeek);
			return;
		}

		showLoading();

		ClientServices.weekService.getWeek(weekNumber, new AsyncCallback<Week>() {
			@Override
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			@Override
			public void onSuccess(Week result) {
				if (result != null) {
					WeekViewer.this.cache.put(result.getWeekNumber(), result);
					setWeek(result);
				}
			}
		});
	}

	private void setWeek(Week week) {
		if (this.week == week) {
			return;
		}
		this.week = week;

		update();
	}

	private void showLoading() {
		Book.getInstance().showLoading();

		getElement().getStyle().setBackgroundImage("");
		getElement().getStyle().setBackgroundColor(null);
		this.icon.getStyle().setDisplay(Display.NONE);
		this.layoutTable.addClassName("hide");
	}

	private void update() {
		if (this.week == null) {
			return;
		}

		this.leftMusicViewer.setMusic(this.week.getMusic1());
		this.rightMusicViewer.setMusic(this.week.getMusic2());

	}

	@Override
	public void loadFinished(MusicViewer source) {
		if (!this.leftMusicViewer.isLoading() && !this.rightMusicViewer.isLoading()) {
			finishLoading();
		}

	}
}
